package com.shareyi.springcore.beanlife;

import com.shareyi.springcore.bean.HelloBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Service;

import java.beans.PropertyDescriptor;

/**
 *
 * InstantiationAwareBeanPostProcessor 接口本质是BeanPostProcessor的子接口，
 * 一般我们继承Spring为其提供的适配器类InstantiationAwareBeanPostProcessor Adapter来使用它
 *
 *
 *
 *
 * Created by david on 2017/5/14.
 */
@Service
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{

    /**
     *   接口方法、实例化Bean之前调用
     *   我们注意到，这个方法会返回一个Object对象，这个对象有什么用呢？
     *
     *   感觉是不是如果已经有对象了，就不在重新生成了？
     *   答案：测试发现，如果这里返回了对象，之后bean就不会被创建，值也不会被设置，BeanPostProcessor也不会再进入，相当于所有的对象初始化都必须在这儿处理完成。spring不陪我们玩耍了~
     *
     *   所以还是默认返回：null 吧
     */
     @Override
     public Object postProcessBeforeInstantiation(Class beanClass,
             String beanName) throws BeansException {
                System.out
                        .println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
               /* if(beanClass== HelloBean.class){
                    HelloBean helloBean=new HelloBean();
                    helloBean.setName("我尼玛是在bean准备生成的时候调用的，看看我能不能直接替换掉你意向中的对象？");
                    helloBean.setFlag("我是一个被拦截生成的对象");
                    return helloBean;
                }*/
                return null;
            }

    /**
     * 接口方法、实例化Bean之后调用
     *  实例化之后，相对于BeanPostProcessor来说，要先调用这儿， 是bean的构造周期！
     */

    @Override
     public Object postProcessAfterInitialization(Object bean, String beanName)
             throws BeansException {
                System.out
                        .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
                return bean;
             }

    /**
     * 接口方法、设置某个属性时调用
     *
     * 这儿会传入你在property属性上设置的所有值，有个问题， 注解的resource会被传入么？
     *
     * 这儿的用处：
     *
     * 可以修改property值，拦截一些非法注入
     *
     * 不过一般不怎么用得着！
     *
     */

    @Override
     public PropertyValues postProcessPropertyValues(PropertyValues pvs,
                                                     PropertyDescriptor[] pds, Object bean, String beanName)
             throws BeansException {
                 System.out
                         .println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
                 return pvs;
            }

}
